import java.awt.Component;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JSlider;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JColorChooser;
import javax.swing.JTextField;

/**
 * A JPanel that allows the user to apply settings to the game
 */
public class SettingsPanel extends JPanel implements ActionListener, ChangeListener
{
	public static final Color DEFAULT_CIRCLE_COLOR= Color.BLACK;
	public static final Color DEFAULT_BACKGROUND_COLOR= Color.WHITE;
	private JTextField maxCircles;
	private JTextField minCircles;
	private JButton logout;
	private JButton showStats;
	private JButton showCircleColor;
	private JButton showBackground;
	private JButton go;
	private JLabel message;
	private JPanel circlePanel;
	private JSlider circleSize;
	private JDialog dialog;
	private Color circleColor= DEFAULT_CIRCLE_COLOR;
	private Color background= DEFAULT_BACKGROUND_COLOR;
	private Circle testCircle;
	private static final int MAX_CIRCLE_SIZE= 70;
	private static final int MIN_CIRCLE_SIZE= 10;
	int max; 
	int min;
	
	public SettingsPanel()
	{
		setBackground(Color.WHITE);
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		testCircle= new Circle(DEFAULT_CIRCLE_COLOR, 0, 0, SubitizePanel.DEFAULT_CIRCLE_SIZE);
		JLabel maxLabel= new JLabel("Maximum Number of Circles(1-20)");
		maxLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel minLabel= new JLabel("Minimum Number of Circles(1-17)");
		minLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		maxCircles= new JTextField("5", 3);
		maxCircles.setAlignmentX(Component.CENTER_ALIGNMENT);
		minCircles= new JTextField("1", 3);
		minCircles.setAlignmentX(Component.CENTER_ALIGNMENT);
		logout= new JButton("Logout");
		logout.setAlignmentX(Component.CENTER_ALIGNMENT);
		logout.setMnemonic(KeyEvent.VK_L);
		showStats= new JButton("Show Stats");
		showStats.setAlignmentX(Component.CENTER_ALIGNMENT);
		showStats.setMnemonic(KeyEvent.VK_S);
		showCircleColor= new JButton("Choose Circle Color");
		showCircleColor.setAlignmentX(Component.CENTER_ALIGNMENT);
		showCircleColor.setMnemonic(KeyEvent.VK_C);
		showBackground= new JButton("Choose Background Color");
		showBackground.setAlignmentX(Component.CENTER_ALIGNMENT);
		showBackground.setMnemonic(KeyEvent.VK_B);
		go= new JButton("Go");
		go.setAlignmentX(Component.CENTER_ALIGNMENT);
		go.setMnemonic(KeyEvent.VK_G);
		circlePanel= new JPanel()
		{
			public void paintComponent(Graphics g)
			{
				super.paintComponent(g);
				testCircle.setX(this.getWidth()/2-testCircle.getSize()/2);
				testCircle.setY(0);
				testCircle.drawCircle(g);
			}
		};
		circlePanel.setMinimumSize(new Dimension(MAX_CIRCLE_SIZE*2,
				                                 MAX_CIRCLE_SIZE));
		circlePanel.setPreferredSize(new Dimension(MAX_CIRCLE_SIZE*2,
                MAX_CIRCLE_SIZE));
		circlePanel.setMaximumSize(new Dimension(MAX_CIRCLE_SIZE*2,
                MAX_CIRCLE_SIZE));
		circlePanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		circlePanel.setBackground(Color.WHITE);
		circleSize= new JSlider(MIN_CIRCLE_SIZE, MAX_CIRCLE_SIZE, 
								SubitizePanel.DEFAULT_CIRCLE_SIZE);
		circleSize.setAlignmentX(Component.CENTER_ALIGNMENT);
		circleSize.setMajorTickSpacing(10);
		circleSize.setPaintTicks(true);
		circleSize.setPaintLabels(true);
		circleSize.setMaximumSize(new Dimension(300, 50));
		circleSize.setBackground(Color.WHITE);
		circleSize.addChangeListener(this);
		message= new JLabel("");
		message.setAlignmentX(Component.CENTER_ALIGNMENT);
		maxCircles.setMaximumSize(new Dimension(40, 20));
		minCircles.setMaximumSize(new Dimension(40, 20));
		add(logout);
		add(showStats);
		add(maxLabel);
		add(maxCircles);
		add(minLabel);
		add(minCircles);
		add(showCircleColor);
		add(showBackground);
		add(circlePanel);
		add(circleSize);
		add(go);
		add(message);
		logout.addActionListener(this);
		showStats.addActionListener(this);
		showCircleColor.addActionListener(this);
		showBackground.addActionListener(this);
		go.addActionListener(this);
		maxCircles.setActionCommand(go.getActionCommand());
		minCircles.setActionCommand(go.getActionCommand());
		maxCircles.addActionListener(this);
		minCircles.addActionListener(this);
		circlePanel.setSize(new Dimension(MAX_CIRCLE_SIZE*2,
				 MAX_CIRCLE_SIZE));
		dialog= new JDialog(new Frame(), "Stats");
		StatsPane statsPane= new StatsPane(Global.currentUser);
		dialog.setContentPane(statsPane);
		dialog.setSize(new Dimension(500, 500));
		dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
		dialog.setVisible(false);
	}
	
	/**
	 * Allows the user to customize the settings based on their input.
	 * May change the background or the color of the test circle based on
	 * user input.
	 */
	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if(e.getActionCommand()==showCircleColor.getActionCommand())
		{
			Color oldColor= circleColor;
			circleColor= JColorChooser.showDialog(this, "Pick the Color for the Circles", 
													   oldColor);
			if(circleColor==null) circleColor= oldColor;
			testCircle.setColor(circleColor);
			repaint();
			circlePanel.repaint();
		}
		
		if(e.getActionCommand()==showBackground.getActionCommand())
		{
			Color oldColor= background;
			background= JColorChooser.showDialog(this, "Pick the Background Color", 
													   oldColor);
			if(background==null) background= oldColor;
			setBackground(background);
			circlePanel.setBackground(background);
			circleSize.setBackground(background);
			repaint();
			circlePanel.repaint();
		}
		
		if(e.getActionCommand()==go.getActionCommand())
		{
			if(validEntries())
			{
				replacePanel(new SubitizePanel(max, min, testCircle.getSize(), 
							circleColor, background));
			}
			else if(Global.isApplet()==false)
			{
				((JFrame)getTopLevelAncestor()).pack();
			}
		}
		
		if(e.getActionCommand()==logout.getActionCommand())
		{
			try
			{
				Global.currentUser.save();
			}
			catch(IOException ex)
			{
				ex.printStackTrace();
			}
			
			if(Global.isApplet())
			{
				replacePanel(new CreateUserPanel());
			}
			else
			{
				replacePanel(new LoginPanel());
			}
		}
		
		if(e.getActionCommand()==showStats.getActionCommand())
		{
			StatsPane statsPane= new StatsPane(Global.currentUser);
			dialog.setContentPane(statsPane);
			dialog.setLocation(getX(), getY());
			dialog.setVisible(true);
		}
	}
	
	public boolean validEntries()
	{
		boolean entryError= false;
		try
		{
			max= Integer.parseInt(maxCircles.getText());
			min= Integer.parseInt(minCircles.getText());
			if(max>20) 
			{
				entryError= true;
				throw new NumberFormatException("The Max Must Be Between 1 and 20");
			}
			if(max-min<1)
			{
				entryError= true;
				String s= "The Min and Max Values Must Be Different";
				throw new NumberFormatException(s);
			}
			if(min<=0)
			{
				throw new NumberFormatException();
			}
			
			return true;
		}
		catch(NumberFormatException ex)
		{
			if(entryError) message.setText(ex.getMessage());
			else message.setText("Please Enter Vaild Positive Integers");
			return false;
		}
	}
	
	public void replacePanel(JPanel newPanel)
	{
		dialog.dispose();
		setVisible(false);
		Component ancestor= this.getTopLevelAncestor();
		if(Global.isApplet()) 
		{
			JApplet applet= (JApplet)(ancestor);
			applet.setContentPane(newPanel);
		}
		else
		{
			JFrame frame= (JFrame)(ancestor);
			frame.setContentPane(newPanel);
			frame.pack();
		}
	}

	/**
	 * Sets the circle size to the one specified by the JSlider 
	 */
	@Override
	public void stateChanged(ChangeEvent e) 
	{
		testCircle.setSize(circleSize.getValue());
		circlePanel.repaint();
	}

}
